home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / math / gle-3.000 / gle-3 / gle / pass.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  28KB  |  1,060 lines

  1. #include "all.h"
  2.  
  3. #include "global.h"
  4. #include "proto.h"
  5.  
  6. int32 gt_index(OPKEY lkey,char *s);
  7. int include_file(char *s);
  8. int var_set_local(void);
  9. int var_set_global(void);
  10. int var_clear_local(void);
  11. int get_cap(TOKENS tk,int *ntok,int *curtok,int32 *pcode,int *plen);
  12. int get_join(TOKENS tk,int *ntok,int *curtok,int32 *pcode,int *plen);
  13. int g_marker_def(char *s1, char *s2);
  14. char *mixed_case(char *s);
  15. extern int this_line;
  16.  
  17. #define true (!false)
  18. #define false 0
  19. #define tok(n)  (*tk)[n]
  20. extern int gle_debug;
  21.  
  22. struct sub_st {char name[40];int typ; int np
  23.         ; int ptyp[20]; char *pname[20]; }  ;
  24. struct sub_st *psub;
  25. /*---------------------------------------------------------------------------*/
  26. #define no_more()  if (curtok<=*ntok) gprint("Unexpected text on end of command {%s}\n",tok(curtok));
  27. #define lkeypos(i)  (pcode + *plen + (*lkey)[i].pos - 1);
  28. #define dup_err if (*pt!=0) gprint("Duplicate or illegal combination of qualifiers \n");
  29. #define get_xy() gt_xy(&curtok,tk,ntok,pcode,plen)
  30. #define get_first(key) gt_first((OPKEY) key,&curtok,(TOKENS) tk,ntok,pcode,plen)
  31. #define get_optional(key) gt_optional((OPKEY) key,&curtok,(TOKENS) tk,ntok,pcode,plen)
  32. #define skip_space  if (*tok(curtok)==' ') {curtok++;}
  33. #define get_anyexp() {etype=0;polish(tok(curtok++),(char *) pcode,plen,&etype);}
  34. #define get_exp() {etype=1;polish(tok(curtok++),(char *) pcode,plen,&etype);}
  35. #define get_strexp() {etype=2;polish(tok(curtok++),(char *) pcode,plen,&etype);}
  36. #define get_token(t) if (strcmp(t,tok(curtok))!=0) gprint("Expecting {%s} found {%s} %d \n",t,tok(curtok),curtok); curtok += 1
  37. #define dbg if ((gle_debug & 8)>0)
  38.  
  39. /* pos=   Offset to find the data            */
  40. /* idx=   For switches, which can only have one value.     */
  41. /* The pos is the order the items will be placed in the pcode */
  42. /*---------------------------------------------------------------------------*/
  43. /* Input is gle command (tokized) , output is pcode */
  44. static int cur_mode=0;  /* 0 = normal, 1 = external begin...end */
  45. pass_checkmode()
  46. {
  47.     if (cur_mode!=0) gprint("END OF FILE while in block type %d \n",cur_mode);
  48.     cur_mode = 0; /* reset it */
  49. }
  50. passt(int srclin,char *source,TOKENS tk,int *ntok,int32 *pcode,int *plen)
  51. {
  52.         /* Source line number */
  53.         /* a pointer to the original string */
  54.         /* a pointer to an array of 500 pointers to char tokens */
  55.         /* pinter to number of tokens */
  56.         /* a pointer to the pcode output buffer */
  57.         /* a pointer to the length of the pcode output */
  58. int etype;
  59. static int sdx;
  60. static int sub_start,sub_end;
  61. static char tempstr[300];
  62. static char *sp;
  63. static int *savep;
  64. static int i,f,vtyp,v,sl,np,in_sub,vidx,vtype;
  65.     int ix;
  66.     int curtok=1;
  67.  
  68.     vtype = 0;
  69.     this_line = srclin;
  70.     etype = 1;
  71.     curtok = 1;
  72.     if (cur_mode!=0) {goto text_mode;}
  73.  
  74.     dbg for (i=1;i<= *ntok; i++) gprint("{%s}%d ",tok(i),strlen(tok(i)));
  75.     dbg gprint("\n");
  76.  
  77.     if (*ntok==0) { /* blank line */
  78.         *(pcode+(*plen)++) = 0;
  79.         return;
  80.     }
  81.     find_mkey(tok(1),&ix);
  82.     if (ix==0) {
  83.         if (*tok(1)=='@') { /* call subroutine */
  84.             char tmpexp[232];
  85.             *(pcode+(*plen)++) = 52;
  86.             curtok = 2;
  87.             strcpy(tmpexp,tok(1)+1);
  88.             strcat(tmpexp,"(");
  89.             if (curtok > *ntok) strcat(tmpexp,",");
  90.             while (curtok <= *ntok) {
  91.                 strcat(tmpexp,tok(curtok++));
  92.                 strcat(tmpexp,",");
  93.             }
  94.             tmpexp[strlen(tmpexp)-1] = ')';
  95.             etype = 0;
  96.             polish(tmpexp,(char *) pcode,plen,&etype);
  97.             return ;
  98.         }
  99.         if (strcmp(tok(2),"=")==0) {  /* variable = expression */
  100.             *(pcode+(*plen)++) = 51;
  101.             var_find(tok(1),&vidx,&vtype);
  102.             if (vidx<0) var_add(tok(1),&vidx,&vtype);
  103.             *(pcode+(*plen)++) = vidx;
  104.             curtok = 3;
  105.             polish(tok(curtok++),(char *) pcode,plen,&vtype);
  106.             if (*ntok >= curtok)  gprint("Remove spaces from expression \n");
  107.             return ;
  108.         }
  109.         sp = strchr(tok(curtok),'=');
  110.         if (sp!=NULL) {
  111.             *sp = 0;
  112.             var_findadd(tok(curtok),&vidx,&vtype);
  113.             tok(curtok) = sp + 1;
  114.             *(pcode+(*plen)++) = 51;
  115.             *(pcode+(*plen)++) = vidx;
  116.             curtok = 1;
  117.             polish(tok(curtok++),(char *) pcode,plen,&vtype);
  118.             if (*ntok >= curtok)  gprint("No spaces in expressions\n");
  119.             return ;
  120.         }
  121.     }
  122.     *(pcode+(*plen)++) = ix;
  123.     curtok = 2;
  124.     switch (ix) {
  125.       case 1:  /* ALINE */
  126.         get_xy();
  127.         get_optional(op_line);
  128.         break;
  129.       case 2: /* AMOVE */
  130.         get_xy();
  131.         break;
  132.       case 3: /* ARC r a1 a2  */
  133.         get_exp();
  134.         get_xy();
  135.         get_optional(op_arc);
  136.         no_more();
  137.         break;
  138.       case 4: /* ARCTO x1 y1 x2 y2 r */
  139.         get_xy();
  140.         get_xy();
  141.         get_exp();
  142.         no_more();
  143.         break;
  144.       case 5: /* BEGIN  "PATH"  "BOX"  "SCALE"  "ROTATE"  "TRANSLATE" shear */
  145.         f = get_first(op_begin);
  146.         *(pcode+(*plen)++) = f;
  147.         spush(51);
  148.         /*------------------------------------------*/
  149.         /*       Check if begin variable matches    */
  150.         /*------------------------------------------*/
  151.         switch (f) {
  152.           case 1: /* path */
  153.             get_optional(op_begin_path);
  154.             break;
  155.           case 2: /* box */
  156.             get_optional(op_begin_box);
  157.             break;
  158.           case 3: /* scale */
  159.             get_xy();
  160.             /* get_optional(op_begin_scale); */
  161.             no_more();
  162.             break;
  163.           case 21: /* shear */
  164.             get_xy();
  165.             /* get_optional(op_begin_scale); */
  166.             no_more();
  167.             break;
  168.           case 4: /* rotate */
  169.             get_exp();
  170.             /* get_optional(op_begin_scale); */
  171.             no_more();
  172.             break;
  173.           case 5: /* translate */
  174.             get_xy();
  175. /*            get_optional(op_begin_scale); */
  176.             no_more();
  177.             break;
  178.           case 19: /* clip */
  179.           case 17: /* origin */
  180.             break;
  181.           case 6: /* if */
  182.             break;
  183.           case 7: /* sub */
  184.             gprint("Not a valid begin option\n");
  185.             break;
  186.           case 8: /* name joe */
  187.             get_strexp();
  188.             break;
  189.           case 9: /* text */
  190.             cur_mode = 9;
  191.             get_optional(op_begin_text);
  192.             break;
  193.           case 10: /* graph */
  194.             cur_mode = 10;
  195.             break;
  196.           case 11: /* xaxis */
  197.             cur_mode = 11;
  198.             break;
  199.           case 12: /* yaxis */
  200.             cur_mode = 12;
  201.             break;
  202.           case 13: /* x2axis */
  203.             cur_mode = 13;
  204.             break;
  205.           case 14: /* y2axis */
  206.             cur_mode = 14;
  207.             break;
  208.           case 15: /* curve */
  209.             break;
  210.           case 16: /* KEY */
  211.             cur_mode = 16;
  212.             break;
  213.           case 18: /* table */
  214.             cur_mode = 18;
  215.             break;
  216.         }
  217.         /* here should copy source line across for "begin width 3 */
  218.         if (cur_mode>0)    *(pcode+(*plen)++) = 0;
  219.         break;
  220.       case 6: /* BEZIER x1 y1 x2 y2 x3 y3 */
  221.         get_xy();
  222.         get_xy();
  223.         get_xy();
  224.         no_more();
  225.         break;
  226.       case 7 :    /* box x y  [left | center | right]  [fill xxx] name*/
  227.         get_xy();
  228.         get_optional(op_box);
  229.         break;
  230.       case 52: /* call subroutine */
  231.         {
  232.             char tmpexp[232];
  233.             strcpy(tmpexp,tok(curtok++));
  234.             strcat(tmpexp,"(");
  235.             while (curtok <= *ntok) {
  236.                 strcat(tmpexp,tok(curtok++));
  237.                 strcat(tmpexp,",");
  238.             }
  239.             tmpexp[strlen(tmpexp)-1] = ')';
  240.             etype = 0;
  241.             polish(tmpexp,(char *) pcode,plen,&etype);
  242.         }
  243.         break;
  244.       case 8 :    /* circle rad fill */
  245.         get_exp();
  246.         get_optional(op_circle);
  247.         break;
  248.       case 9 : /* close */
  249.         get_exp();
  250.         no_more();
  251.         break;
  252.       case 53: /* comment !  or blank line */
  253.         break;
  254.       case 10 : /* curve sx sy x y x y x y ... ex ey */
  255.         while (*ntok>curtok) {
  256.             *(pcode+(*plen)++) = 111;
  257.             get_xy();
  258.         }
  259.         *(pcode+(*plen)++) = 999;
  260.         break;
  261.       case 60 : /* defmarker xyz rm 33 1 -.4 -.2 */
  262.         g_defmarker(tok(curtok),tok(curtok+1),atoi(tok(curtok+2))
  263.             ,atof(tok(curtok+4)),atof(tok(curtok+5))
  264.             ,atof(tok(curtok+3)),true);
  265.         break;
  266.       case 11 :  /* define marker jj subname */
  267.         get_token("MARKER");
  268.         g_marker_def(tok(curtok),tok(curtok+1));
  269.         curtok+=2;
  270.         no_more();
  271.         break;
  272.       case 12 :
  273.         sl = strlen(source)+1;
  274.         sl = ((sl + 3) & 0xfffc);
  275.         sl = sl/4;
  276.         /* copy source string to pcode., add null, round upp.      */
  277.         strcpy((char *) (pcode+*plen),source);
  278.         *plen = *plen + sl;
  279.         break;
  280.       case 13 :/* ELSE ... */
  281.         scheck(50);
  282.         no_more();
  283.         break;
  284.       case 14 : /* END if, sub, path, box, scale,translate,rotate */
  285.         i = get_optional(op_begin);
  286.         if (i==7) {
  287.             sub_end = srclin;
  288.             sub_set_startend(sdx,sub_start,sub_end);
  289.             var_clear_local();
  290.             in_sub = false;
  291.         }
  292.         if (i==0) gprint("Type of END missing, e.g. end if, end sub\n");
  293.         spop(i+50);    /* Check if begin variable matches */
  294.         break;
  295.       case 16 : /* FILL (fillpath) */
  296.         no_more();
  297.         break;
  298.       case 15 : /* FCLOSE inchan */
  299.         get_exp();
  300.         break;
  301.       case 17: /* fopen "a.a" inchan read|write */
  302.         get_strexp();
  303.         var_findadd(tok(curtok),&v,&vtyp);
  304.         curtok++;
  305.         *(pcode+(*plen)++) = v;
  306.         if (strcmp(tok(curtok),"WRITE")==0) *(pcode+(*plen)++) = 1;
  307.         else {
  308.             get_token("READ");
  309.             *(pcode+(*plen)++) = 0;
  310.         }
  311.       case 61 : /* fread CHAN a$ x   */
  312.       case 62 : /* freadln */
  313.         while (curtok<=*ntok) {
  314.             var_findadd(tok(curtok),&v,&vtyp); curtok++;
  315.             *(pcode+(*plen)++) = 49;
  316.             *(pcode+(*plen)++) = v;
  317.             *(pcode+(*plen)++) = vtyp;
  318.             skip_space;
  319.         }
  320.         break;
  321.       case 63 : /* fwrite */
  322.       case 64 : /* fwriteln */
  323.         while (curtok<=*ntok) {
  324.             *(pcode+(*plen)++) = 49;
  325.             *(pcode+(*plen)) = 0;
  326.             savep = (int *) (pcode+(*plen)++);
  327.             get_anyexp();
  328.             *savep = etype;
  329.             skip_space;
  330.         }
  331.         break;
  332.       case 18 :  /* for var = exp1 to exp2 [step exp3] */
  333.         sp = strchr(tok(curtok),'=');
  334.         if (sp!=NULL) {
  335.             *sp = 0;
  336.             var_findadd(tok(curtok),&v,&vtyp);
  337.             tok(curtok) = sp + 1;
  338.             *(pcode+(*plen)++) = v;
  339.             spush(v+100);    /* Remeber we started a loop with variable v*/
  340.         } else {
  341.             var_findadd(tok(curtok++),&v,&vtyp);
  342.             *(pcode+(*plen)++) = v;
  343.             spush(v+100);    /* Remeber we started a loop with variable v*/
  344.             get_token("=");
  345.         }
  346.         get_exp();
  347.         get_token("TO");
  348.         get_exp();
  349.         get_optional(op_for_step);
  350.         break;
  351.       case 19 :/* goto */
  352.         gprint("Goto IS NOT implemented, being kept or a future release.\n");
  353.         break;
  354.       case 20 : /* gsave */
  355.         no_more();
  356.         break;
  357.       case 54 : /* grestore */
  358.         no_more();
  359.         break;
  360.       case 21 : /* icon x y */
  361.         get_xy();
  362.         no_more();
  363.         break;
  364.       case 22 :  /* IF exp THEN ...  */
  365.         get_exp();
  366.         get_token("THEN");
  367.         no_more();
  368.         spush(50);    /* Check if endif or else matches */
  369.         break;
  370.       case 55 : /* postscript file$  width  height */
  371.         get_strexp();
  372.         get_xy();
  373.         no_more();
  374.         break;
  375.       case 56 : /* draw file$, nope, not a good idea. begin..end text */
  376.         get_strexp();
  377.         no_more();
  378.         break;
  379.       case 57 : /* plotter fonts */
  380.         get_token("FONTS");
  381.         no_more();
  382.         break;
  383.       case 23 : /* include "string" */
  384.         include_file(mixed_case(tok(curtok++)));
  385.         no_more();
  386.         break;
  387.       case 58 : /* bigfile "string" This waits until 'run' to read the file*/
  388.         get_strexp();
  389.         no_more();
  390.         break;
  391.       case 24 : /* input 1 a$=20,fill$=10,j=6 prompt "Age and name " */
  392.               /* input 1 a$,yval prompt "Age and name " */
  393.       case 25 : /* join a.tl->b.br   ,   string, arrows&line, string */
  394.         get_strexp();
  395.         *(pcode+(*plen)++) = get_first(op_joinname);
  396.         get_strexp();
  397.         break;
  398.       case 26 : /* marker square [2.2] */
  399.         get_marker(tk,ntok,&curtok,pcode,plen);
  400.         if (*ntok<curtok) {
  401.             *(pcode+(*plen)++) = 0;
  402.         } else {
  403.             get_exp();
  404.         }
  405.         break;
  406.       case 27 : /* MOVE name */
  407.         get_strexp();
  408.         no_more();
  409.         break;
  410.       case 28 : /* narc, Arc in clockwise direction */
  411.         get_exp();
  412.         get_xy();
  413.         get_optional(op_arc);
  414.         no_more();
  415.         break;
  416.       case 29 : /* newpath */
  417.         no_more();
  418.         break;
  419.       case 30 : /* next */
  420.         if (curtok<=*ntok) get_exp();
  421.         spop(v+100);    /* Check if loop variable matches */
  422.         no_more();
  423.         break;
  424.       case 31 : /* pie r a1 a2 fill pattern */
  425.         get_exp();
  426.         get_xy();
  427.         get_optional(op_fill);
  428.         break;
  429.       case 32 : /*print 0 "Working..." */
  430.       case 33 :
  431.         get_xy();
  432.         get_xy();
  433.         get_xy();
  434.         no_more();
  435.         break;
  436.       case 34 : /* region */
  437.         gprint("Region IS NOT implemented, complain to your local MP   \n");
  438.         break;
  439.       case 50 : /* Return EXP */
  440.         if (curtok<=*ntok) {
  441.             get_exp();
  442.         } else {        
  443.           etype=1;polish("0",(char *) pcode,plen,&etype);
  444.         }
  445.         break;
  446.       case 35 : /* Reverse the current path */
  447.         no_more();
  448.         break;
  449.       case 36 : /* rline */
  450.         get_xy();
  451.         get_optional(op_line);
  452.         break;
  453.       case 37 : /* rmove */
  454.         get_xy();
  455.         no_more();
  456.         break;
  457.       case 38 : /* rotate */
  458.         get_exp();
  459.         no_more();
  460.         break;
  461.       case 39 : /* save joe */
  462.         get_strexp();
  463.         no_more();
  464.         break;
  465.       case 40 : /* scale x y */
  466.         get_xy();
  467.         no_more();
  468.         break;
  469.       case 41 : /* SET color font hei just lwidth lstyle ldist */
  470.         while (curtok<=*ntok) {
  471.          dbg gprint(" set ntok= %d  curtok= %d \n",curtok,*ntok);
  472.          f = get_first(op_set);
  473.          *(pcode+(*plen)++) = 500+f;
  474.          switch (f) {
  475.           case 1: /* height */
  476.             get_exp();
  477.             break;
  478.           case 2: /* font */
  479.             get_font(tk,ntok,&curtok,pcode,plen);
  480.             break;
  481.           case 3: /* justify */
  482.             get_justify(tk,ntok,&curtok,pcode,plen);
  483.             break;
  484.           case 4: /* color */
  485.             get_color(tk,ntok,&curtok,pcode,plen);
  486.             break;
  487.           case 5: /* dashlen */
  488.             get_exp();
  489.             break;
  490.           case 6: /* dash */
  491.             get_exp();
  492.             break;
  493.           case 7: /* lwidth */
  494.             get_exp();
  495.             break;
  496.           case 8: /* join */
  497.             /* get_join(); */
  498.             get_join(tk,ntok,&curtok,pcode,plen);
  499.             break;
  500.           case 9: /* cap */
  501.             /* get_cap(); */
  502.             get_cap(tk,ntok,&curtok,pcode,plen);
  503.             break;
  504.           case 10: /* fontlwidth */
  505.             get_exp();
  506.             break;
  507.           }
  508.         }
  509.         break;
  510.       case 42 : /* size */
  511.         get_xy();
  512.         get_optional(op_size);
  513.         break;
  514.       case 43 : /* STROKE */
  515.         no_more();
  516.         break;
  517.       case 44 : /* SUB JOE X Y$ Z   ... END SUB  */
  518.         if (in_sub) {gprint("Cannot define a subroutine within a sub "); break;}
  519.         in_sub = true;
  520.         spush(51);        /* to check structure */
  521.         sdx = sub_def(tok(curtok++));
  522.         var_set_local();
  523.         if (!valid_var(psub->name)) {
  524.             gprint("Invalid subroutine name ");
  525.         }
  526.         for (np=0; curtok<=*ntok; np++) {
  527.             sub_param(sdx,tok(curtok));
  528.             if (!valid_var(tok(curtok))) {
  529.                 gprint("Invalid subroutine parameter");
  530.             }
  531.             curtok++;
  532.         }
  533.         *(pcode+(*plen)++) = sdx; /* put sub number in pcode */
  534.         sub_start = srclin;
  535.         var_set_global();
  536.         break;
  537.       case 45 :
  538.         /* char *source;    a pointer to the original string */
  539.         /* produce captilized string                 */
  540.         for (i=0; *(source+i)!=0; i++)
  541.             tempstr[i] = toupper(*(source+i));
  542.         /* find word TEXT                      */
  543.         sp = strstr(tempstr,"TEXT");
  544.         if (sp==NULL) {gprint("what the shit \n"); break;}
  545.                         /* sp = &tempstr;    */
  546.         sp = (sp-&tempstr[0])+source;    /* switch to lowercase str */
  547.         sp = sp + 5;
  548.         sl = strlen(sp)+1;
  549.         sl = ((sl + 3) & 0xfffc);
  550.         sl = sl/4;
  551.         /* copy rest of string to pcode., add null, round upp.      */
  552.         strcpy((char *) (pcode+*plen),sp);
  553.         *plen = *plen + sl;
  554.         break;
  555.       case 59 : /* textdef */
  556.         /* char *source;    a pointer to the original string */
  557.         /* produce captilized string                 */
  558.         for (i=0; *(source+i)!=0; i++)
  559.             tempstr[i] = toupper(*(source+i));
  560.         /* find word TEXT                      */
  561.         sp = strstr(tempstr,"TEXTDEF");
  562.         if (sp==NULL) {gprint("what the shit \n"); break;}
  563.                         /* sp = &tempstr;    */
  564.         sp = (sp-&tempstr[0])+source;    /* switch to lowercase str */
  565.         sp = sp + 8;
  566.         sl = strlen(sp)+1;
  567.         sl = ((sl + 3) & 0xfffc);
  568.         sl = sl/4;
  569.         /* copy rest of string to pcode., add null, round upp.      */
  570.         strcpy((char *) (pcode+*plen),sp);
  571.         *plen = *plen + sl;
  572.         break;
  573.       case 46 : /* translate x y */
  574.         get_xy();
  575.         no_more();
  576.         break;
  577.       case 47 : /* until */
  578.         get_exp();
  579.         spush(50+20);
  580.         break;
  581.       case 48 : /* while */
  582.         gprint("While IS NOT implemented, complain to your local MP   \n");
  583.         break;
  584.       case 49 : /* write numexp,strexp,strexp */
  585.         while (curtok<=*ntok) {
  586.             *(pcode+(*plen)++) = 49;
  587.             *(pcode+(*plen)) = 0;
  588.             savep = (int *) (pcode+(*plen)++);
  589.             get_anyexp();
  590.             *savep = etype;
  591.             skip_space;
  592.         }
  593.         break;
  594.       default:
  595.         gprint("Unrecognised command verb {%s}   %d \n",tok(1),ix);
  596.         if (strchr(tok(1),'=')!=NULL)
  597.             gprint("There should be a space on either side of an equals sign \n");
  598.  
  599.     }
  600. return;
  601.  
  602. /*------------*/
  603. text_mode: /* Inside a begin, don't interpret, just pass "as is" */
  604.     *(pcode+(*plen)++) = 5;        /* begin */
  605.     if (strcmp(tok(1),"END")==0) {
  606.       i = gt_index((OPKEY) op_begin,tok(2));
  607.       if (i==cur_mode) {
  608.         *(pcode+(*plen)++) = 0;        /* END XXXX */
  609.         cur_mode = 0;
  610.         return;
  611.       }
  612.     }
  613.     *(pcode+(*plen)++) = cur_mode;    /* begin_type (e.g. text, graph, xaxis */
  614.  
  615.     sl = strlen(source)+1;
  616.     *(pcode+*plen) = 0;
  617.     sl = ((sl + 3) & 0xfffc);
  618.     sl = sl/4;
  619.     /* copy source string to pcode., add null, round upp.      */
  620.     strcpy((char *) (pcode+*plen),source);
  621.     *plen = *plen + sl;
  622. }
  623. /*--------------------------------------------------------------------------*/
  624. gt_xy(int *curtok, char (*(*tk)[500]), int *ntok,
  625.     int32 *pcode, int *plen)
  626. {
  627.     int etype;
  628.     etype = 1;
  629.     if (*ntok < *curtok) {
  630.         gprint("Expecting x expression on end of line\n");
  631.     }
  632.     polish(tok((*curtok)++),(char *) pcode,plen,&etype);
  633.     etype = 1;
  634.     if (*ntok < *curtok) {
  635.         gprint("Expecting y expression on end of line\n");
  636.     }
  637.     polish(tok((*curtok)++),(char *) pcode,plen,&etype);
  638. }
  639. /*--------------------------------------------------------------------------*/
  640. int32 gt_first(OPKEY lkey, int *curtok, TOKENS tk, int *ntok, int32 *pcode, int *plen)
  641. {
  642.     int nk,i,width=0,p;
  643.     for (i=0; (*lkey)[i].typ!=typ_end; i++) {
  644.         p = (*lkey)[i].pos;
  645.         if (p>width) width = p ;
  646.     }
  647.     nk = i;
  648.     for (i=0; i<nk; i++) {
  649.         if (strcmp((*lkey)[i].name,tok(*curtok))==0) {
  650.             (*curtok)++;
  651.             return (*lkey)[i].idx;
  652.         }
  653.     }
  654.     gprint("Found {%s} expecting one of: \n",tok(*curtok));
  655.     gprint("        ");
  656.     for (i=0; i<nk; i++) {
  657.         gprint("%s, ",(*lkey)[i].name);
  658.         if ( (i+1)/3 == (i+1)/3.0 ) gprint("\n        ");
  659.     }
  660.     if ( (i)/3 != (i+1)/3.0 ) gprint("\n");
  661.     (*curtok)++;
  662.  
  663. }
  664. int32 gt_firstval(OPKEY lkey,char *s)
  665. {
  666.     int nk,i,width=0,p;
  667.     for (i=0; (*lkey)[i].typ!=typ_end; i++) {
  668.         p = (*lkey)[i].pos;
  669.         if (p>width) width = p ;
  670.     }
  671.     nk = i;
  672.     for (i=0; i<nk; i++) {
  673.         if (strcmp((*lkey)[i].name,s)==0) {
  674.             dbg gprint("Got match {%s} \n",s);
  675.             return (*lkey)[i].idx;
  676.         }
  677.     }
  678.     gprint("Found {%s} expecting one of: \n",s);
  679.     for (i=0; i<nk; i++) gprint("        %s \n",(*lkey)[i].name);
  680. }
  681.  
  682. int32 gt_index(OPKEY lkey,char *s)
  683. {
  684.     int nk,i,p;
  685.     for (i=0; (*lkey)[i].typ!=typ_end; i++) {
  686.         if (strcmp((*lkey)[i].name,s)==0) {
  687.             return (*lkey)[i].idx;
  688.         }
  689.     }
  690.     return 0;
  691. }
  692. /*--------------------------------------------------------------------------*/
  693. gt_optional(OPKEY lkey, int *curtok, TOKENS tk, int *ntok, int32 *pcode, int *plen)
  694. {
  695.     int rval=0;
  696.     int xlen,*pt;
  697.     int etype,f;
  698.     int nk,i,width=0,p,tt,pidx,prest;
  699.  
  700.     for (i=0; (*lkey)[i].typ!=typ_end; i++) {
  701.         p = (*lkey)[i].pos;
  702.         if (p>width) width = p ;
  703.     }
  704.     nk = i;
  705.     /* zero all the optional parameters. */
  706.     for (i=0; i<width+1; i++) {
  707.         *(pcode + i + *plen) = 0;
  708.     }
  709.     dbg gprint("The number of flags %d first token {%s} %d \n",nk,tok(*curtok),*curtok);
  710.     prest = *plen + nk;    /*remeber where the END OF exp'S are */
  711.     for (tt = *curtok; tt<= *ntok; ) {
  712.       for (i=0; i<nk; i++) {
  713.         if (strcmp((*lkey)[i].name,tok(tt))==0) {
  714.             tt++;
  715.             goto found_word;
  716.         }
  717.       }
  718.     *plen = prest;
  719.       gprint("Found {%s} (%d) expecting one of: \n",tok(tt),tt);
  720.       for (i=0; i<nk; i++) gprint("        %s \n",(*lkey)[i].name);
  721.       *curtok = tt;
  722.       return 0;
  723. found_word:
  724. /*----------------------------------------*/
  725. /* switches     int     placed in directly, 1 present, 0 not present
  726. /* expressions     LONG*     pointed to, 0 if not present.
  727. /* color/fill    LONG*     Pointer to exp 0 if not present.
  728. /* marker    LONG*    Pointer to exp 0 if not present.
  729. /* lstyle     LONG*    Pointer to exp 0 if not present.
  730. /* font     int32*     Pointer to string expression.
  731. /* justify     int32
  732. */
  733.  
  734.       switch ((*lkey)[i].typ) {
  735.         case typ_val:
  736.         etype = 1;
  737.         pt = (int *)  (pcode + *plen + (*lkey)[i].pos - 1);
  738.         if (*pt!=0) gprint("Duplicate or illegal combination of qualifiers ");
  739.         *pt = prest-*plen-(*lkey)[i].pos+1;
  740.         polish(tok(tt++),(char *) pcode,&prest,&etype);
  741.         dbg gprint("val Returned,  curtok=%d prest=%d type %d \n",tt,prest,etype);
  742.          break;
  743.         case typ_val2:
  744.         etype = 1;
  745.         pt = (int *) (pcode + *plen + (*lkey)[i].pos - 1);
  746.         if (*pt!=0) gprint("Duplicate or illegal combination of qualifiers ");
  747.         *pt = prest-*plen-(*lkey)[i].pos+1 ;
  748.         polish(tok(tt++),(char *) pcode,&prest,&etype);
  749.         dbg gprint("val Returned,  curtok=%d prest=%d type %d \n",tt,prest,etype);
  750.         /* tt++; */    /* step over space between expressions */
  751.         etype = 1;
  752.         pt = pt + 1;
  753.         if (*pt!=0) gprint("Duplicate or illegal combination of qualifiers ");
  754.         *pt = prest-*plen-(*lkey)[i].pos+1 ;
  755.         polish(tok(tt++),(char *) pcode,&prest,&etype);
  756.         dbg gprint("val Returned,  curtok=%d prest=%d type %d \n",tt,prest,etype);
  757.         break;
  758.         case typ_str: /* string constant,  used for NAMEs, */
  759.         etype = 2;
  760.         pt = (int *) (pcode + *plen + (*lkey)[i].pos - 1);
  761.         if (*pt!=0) gprint("Duplicate or illegal combination of qualifiers %ld %p \n",*pt,pt);
  762.         *pt = prest-*plen-(*lkey)[i].pos+1;
  763.         polish(tok(tt++),(char *) pcode,&prest,&etype);
  764.          break;
  765.         case typ_switch:
  766.         pt = (int *) (pcode + *plen + (*lkey)[i].pos - 1);
  767.         dup_err;
  768.         *pt = (*lkey)[i].idx;
  769.         rval = *pt;
  770.         break;
  771.         case typ_color: /* blue green red, or exp. */
  772.         case typ_fill:
  773.         pt = (int *) lkeypos(i);
  774.         dup_err;
  775.         *pt = prest-*plen-(*lkey)[i].pos+1 ;
  776.         get_fill(tk,ntok,&tt,pcode,&prest);
  777.         break;
  778.         case typ_marker:
  779.         pt = (int *) lkeypos(i);
  780.         dup_err;
  781.         *pt = prest-*plen-(*lkey)[i].pos+1 ;
  782.         get_marker(tk,ntok,&tt,pcode,&prest);
  783.         break;
  784.         case typ_lstyle:
  785.         pt = (int *) lkeypos(i);
  786.         dup_err;
  787.         *pt = prest-*plen-(*lkey)[i].pos+1 ;
  788.         etype = 1;
  789.         polish(tok(tt++),(char *) pcode,&prest,&etype);
  790.         break;
  791.         case typ_justify:
  792.         pt = (int *) lkeypos(i);
  793.         dup_err;
  794.         *pt = gt_first((OPKEY) op_justify,&tt,(TOKENS) tk,ntok,pcode,&prest);
  795.         dbg gprint("setting justify flag %d \n",*pt);
  796.         break;
  797.         case typ_arrow:
  798.         f = gt_first((OPKEY) op_arrow,&tt,(TOKENS) tk,ntok,pcode,&prest);
  799.         pt = (int *) lkeypos(i);
  800.         *pt = f;
  801.         break;
  802.         default :
  803.         gprint("***errrorororororor non existent type ***");
  804.         break;
  805.       }
  806. /*----------------------------------------*/
  807.     }
  808.     *plen = prest;
  809.     *curtok = tt;
  810.     return rval;
  811. }
  812. /*--------------------------------------------------------------------------*/
  813.  
  814. #undef get_first
  815. #define get_first(key) gt_first(&key,curtok,tk,ntok,pcode,plen)
  816.  
  817. /*--------------------------------------------------------------------------*/
  818. mystrcpy(char **d,char *s)
  819. {
  820.     if (*d!=0) myfree(*d);
  821.     *d = 0;
  822.     *d = myallocz(strlen(s)+1);
  823.     strcpy(*d,s);
  824. }
  825. #undef get_exp
  826. #define get_exp() polish(tok((*curtok)++),(char *) pcode,plen,&etype)
  827. /* pos=   Offset to find the data            */
  828. /* idx=   For switches, which can only have one value.     */
  829. /*--------------------------------------------------------------------------*/
  830. int pass_justify(char *s)
  831. {
  832.     return gt_firstval((OPKEY) op_justify,s);
  833. }
  834. int polish_eval(char *s, double *x);
  835. int32 pass_color(char *s)
  836. {
  837.     double xx;
  838.     int32 j;
  839.     int i;
  840.     char vv[80];
  841.     if (strstr(s,"CVTRGB")!=NULL) {
  842.         polish_eval(s,&xx);
  843.     } else if (*s=='.' || *s=='(' || isdigit(*s)) {
  844.         strcpy(vv,"cvtgrey(");
  845.         strcat(vv,s); strcat(vv,")");
  846.         polish_eval(vv,&xx);
  847.     } else    if (strchr(s,'$') != NULL) {
  848.         strcpy(vv,"cvtcolor(");
  849.         strcat(vv,s); strcat(vv,")");
  850.         polish_eval(vv,&xx);
  851.     } else {
  852.         return     gt_firstval((OPKEY) op_color_typ,s);
  853.     }
  854.     memcpy(&j,&xx,sizeof(int32));
  855.     return j;
  856. }
  857. #define get_exps(ss) polish(ss,(char *) pcode,plen,&etype)
  858. get_color(TOKENS tk,int *ntok,int *curtok,int32 *pcode,int *plen)
  859. {
  860.     int i,etype=1;
  861.     char vv[80];
  862.  
  863.     if (strstr(tok(*curtok),"CVTRGB")!=NULL) {
  864.         get_exps(tok(*curtok));
  865.     } else if (*tok(*curtok)=='(' || isdigit(*tok(*curtok))) {
  866.         strcpy(vv,"cvtgrey(");
  867.         strcat(vv,tok(*curtok)); strcat(vv,")");
  868.         get_exps(vv);
  869.     } else    if (strchr(tok(*curtok),'$') != NULL) {
  870.         strcpy(vv,"cvtcolor(");
  871.         strcat(vv,tok(*curtok)); strcat(vv,")");
  872.         get_exps(vv);
  873.     } else {
  874.         *(pcode+(*plen)++) = 8;
  875.         *(pcode+(*plen)++) = get_first(op_color_typ);
  876.         return;
  877.     }
  878.     (*curtok)++;
  879. }
  880. get_fill(TOKENS tk,int *ntok,int *curtok,int32 *pcode,int *plen)
  881. {
  882.     int i,etype=1;
  883.     char vv[80];
  884.     if (strstr(tok(*curtok),"CVTRGB")!=NULL) {
  885.         get_exps(tok(*curtok));
  886.     } else if (*tok(*curtok)=='(' || isdigit(*tok(*curtok))) {
  887.         strcpy(vv,"cvtgrey(");
  888.         strcat(vv,tok(*curtok)); strcat(vv,")");
  889.         get_exps(vv);
  890.     } else    if (strchr(tok(*curtok),'$') != NULL) {
  891.         strcpy(vv,"cvtcolor(");
  892.         strcat(vv,tok(*curtok)); strcat(vv,")");
  893.         get_exps(vv);
  894.     } else {
  895.         *(pcode+(*plen)++) = 8;
  896.         *(pcode+(*plen)++) = get_first(op_color_typ);
  897.         return;
  898.     }
  899.     (*curtok)++;
  900. }
  901. get_justify(TOKENS tk,int *ntok,int *curtok,int32 *pcode,int *plen)
  902. {
  903.     *(pcode+(*plen)++) = get_first(op_justify);
  904. }
  905. get_join(TOKENS tk,int *ntok,int *curtok,int32 *pcode,int *plen)
  906. {
  907.     *(pcode+(*plen)++) = get_first(op_join);
  908. }
  909. get_cap(TOKENS tk,int *ntok,int *curtok,int32 *pcode,int *plen)
  910. {
  911.     *(pcode+(*plen)++) = get_first(op_cap);
  912. }
  913.  
  914. struct mark_struct { char *name; char *font; int cc; double rx; double ry; double scl;};
  915. struct mark_struct stdmark[] = {
  916.         "DOT","RM",46,-.125,-.0435,3.0,        /* dot */
  917.         "CROSS","TEXSY",2,-.375,-.24,1.0,    /* cross */
  918.         "FCIRCLE","GLEMARK",4,-.5,-.5,0.7,    /* fcircle */
  919.         "FSQUARE","GLEMARK",6,-.5,-.5,0.7,    /* fsquare */
  920.         "FTRIANGLE","GLEMARK",5,-.5,-.433,0.7,    /* ftriangle */
  921.         "FDIAMOND","GLEMARK",7,-.5,-.7,0.7,    /* fdiamond */
  922.         "CIRCLE","GLEMARK",12,-.5,-.5,0.7,    /* circle */
  923.         "SQUARE","GLEMARK",2,-.5,-.5,0.7,    /* square */
  924.         "TRIANGLE","GLEMARK",1,-.5,-.433,0.7,    /* triangle */
  925.         "DIAMOND","GLEMARK",3,-.5,-.7,0.7,    /* diamond */
  926.         /*"PLUS","TEXMI",43,-.375,-.24,1.0,*/    /* plus, needs fixing ("+" unavailable in that font) */
  927.         "PLUS","TEXCMR",43,-.375,-.24,1.0,    /* plus, fixed */
  928.         "CLUB","TEXSY",124,-.38,-.3,1.0,    /* club */
  929.         "HEART","TEXSY",126,-.38,-.34,1.0,    /* heart */
  930.         "DIAMONDZ","TEXSY",125,-.38,-.26,1.0,    /* diamondz */
  931.         "SPADE","TEXSY",127,-.375,-.24,1.0,    /* spade (needs fixing) */
  932.         "STAR","TEXMI",63,-.25,-.21,1.0,    /* star */
  933.         "SNAKE","TEXSY",120,-.21,-.22,1.0,    /* snake */
  934.         "DAG","TEXSY",121,-.21,-.22,1.0,    /* dag */
  935.         "DDAG","TEXSY",122,-.21,-.22,1.0,    /* dagg */
  936.         "ASTERIX","TEXSY",3,-.25,-.24,1.0,    /* asterix */
  937.         "ASTERISK","TEXSY",3,-.25,-.24,1.0,    /* asterix */
  938.         "OPLUS","TEXSY",8,-.40,-.24,1.0,    /* oplus */
  939.         "OMINUS","TEXSY",9,-.40,-.24,1.0,    /* ominus */
  940.         "OTIMES","TEXSY",10,-.40,-.24,1.0,    /* otimes */
  941.         "ODOT","TEXSY",12,-.40,-.24,1.0,    /* odot */
  942.         "TRIANGLEZ","TEXSY",52,-.44,-.26,1.0,    /* trianglez */
  943.         "DIAMONDZ","TEXSY",125,-.38,-.26,1.0,    /* diamondz */
  944.         "WCIRCLE","GLEMARK",8,-.5,-.5,0.7,    /* wcircle */
  945.         "WTRIANGLE","GLEMARK",9,-.5,-.433,0.7,    /* wtriangle */
  946.         "WSQUARE","GLEMARK",10,-.5,-.5,0.7,    /* wsquare */
  947.         "WDIAMOND","GLEMARK",11,-.5,-.7,0.7,    /* wdiamond */
  948.         "PLANE","PSZD",40,0.0,0.0,1.0,        /* ZapDingbats */
  949.         "HANDPEN","PSZD",45,0.0,0.0,1.0,    /* ZapDingbats */
  950.         "SCIRCLE","PSZD",109,0.0,0.0,1.0,    /* ZapDingbats */
  951.         "SSQUARE","PSZD",111,0.0,0.0,1.0,    /* ZapDingbats */
  952.         "PHONE","PSZD",37,0.0,0.0,1.0,        /* ZapDingbats */
  953.         "LETTER","PSZD",41,0.0,0.0,1.0,        /* ZapDingbats */
  954.         "STAR2","PSZD",69,0.0,0.0,1.0,        /* ZapDingbats */
  955.         "STAR3","PSZD",79,0.0,0.0,1.0,        /* ZapDingbats */
  956.         "STAR4","PSZD",98,0.0,0.0,1.0,        /* ZapDingbats */
  957.         "FLOWER","PSZD",96,0.0,0.0,1.0,        /* ZapDingbats */
  958.         NULL,NULL,0,0,0,0
  959. };    /* change range check below when adding markers */
  960.  
  961.  
  962.  
  963. char *mark_name[30];
  964. char *mrk_fname[61];
  965. char *mrk_name[61];
  966. char *mark_sub[30];
  967. int mark_subp[30];
  968. int nmark;
  969. int nmrk;
  970. int std_nmrk;
  971. void mark_clear(void)
  972. {
  973.     int i,fg;
  974.     struct mark_struct *p;
  975.     if (std_nmrk==0) {
  976.         for (i=0; stdmark[i].name !=NULL; i++) {
  977.             p = &stdmark[i];
  978.             fg = false;
  979.             if (p->rx==0) fg = true;
  980.             g_defmarker(p->name,p->font,p->cc,p->rx,p->ry
  981.                 ,p->scl,fg);
  982.         }
  983.         std_nmrk = nmrk;
  984.     }
  985.     for (i=0; i<nmark; i++) {
  986.       if (mark_sub[i]!=NULL) { myfree(mark_sub[i]); mark_sub[i]=NULL;}
  987.       if (mark_name[i]!=NULL) { myfree(mark_name[i]); mark_name[i]=NULL;}
  988.     }
  989.     for (i=std_nmrk; i<nmrk; i++) {
  990.       if (mrk_name[i]!=NULL) { myfree(mrk_name[i]); mrk_name[i]=NULL;}
  991.       if (mrk_fname[i]!=NULL) { myfree(mrk_fname[i]); mrk_fname[i]=NULL;}
  992.     }
  993.     nmrk = std_nmrk;
  994.     nmark = 0;
  995. }
  996. get_marker(TOKENS tk,int *ntok,int *curtok,int32 *pcode,int *plen)
  997. {
  998.     int i,etype=1;
  999.     char vv[80];
  1000.     if (*tok(*curtok)=='(' || isdigit(*tok(*curtok))) {
  1001.         strcpy(vv,"cvtint(");
  1002.         strcat(vv,tok(*curtok)); strcat(vv,")");
  1003.         get_exps(vv);
  1004.     } else    if (strchr(tok(*curtok),'$') != NULL) {
  1005.         strcpy(vv,"cvtmarker(");
  1006.         strcat(vv,tok(*curtok)); strcat(vv,")");
  1007.         get_exps(vv);
  1008.     } else {
  1009.         *(pcode+(*plen)++) = 8;
  1010.         *(pcode+(*plen)++) = pass_marker(tok(*curtok));
  1011.     }
  1012.     (*curtok)++;
  1013. }
  1014. pass_marker(char *s)
  1015. {
  1016.     int i;
  1017.     int32 f=0;
  1018.     /* if 0, maybe its a user defined marker, ie a subroutine */
  1019.     /* Use -ve to signify subroutine instead of normal marker */
  1020.     for (i=0; i<nmark; i++) {
  1021.         if (strcmp(mark_name[i],s)==0) {
  1022.             f = -(++i);
  1023.             break;
  1024.         }
  1025.     }
  1026.     if (f==0)  {
  1027.         for (i=nmrk-1; i>=0; i--) {
  1028.             if (strcmp(mrk_name[i],s)==0) {
  1029.                 f = ++i;
  1030.                 break;
  1031.             }
  1032.         }
  1033.     }
  1034.     if (f==0) gprint("Invalid marker name {%s} \n",s);
  1035.     return f;
  1036. }
  1037.  
  1038.  
  1039. spop(int v)
  1040. {
  1041. }
  1042. spush(int v)
  1043. {
  1044. }
  1045. scheck(int v)
  1046. {
  1047. }
  1048.  
  1049. char *mixed_case(char *s)
  1050. {
  1051.     if (*s == '"') {
  1052.         s[strlen(s)-1] = 0;
  1053.         return s+1;
  1054.     }
  1055.     return strlwr(s);
  1056. }
  1057.  
  1058.  
  1059.  
  1060.